package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.LanguageManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.Util.IEEE754Utils;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Mxcwsensor;
import com.example.onlinemonitoring.model.common.MyResult;
import com.example.onlinemonitoring.model.Yggxhistory;
import com.example.onlinemonitoring.model.Yggxsensor;
import com.example.onlinemonitoring.query.QueryObject;
import org.springframework.context.annotation.Scope;
import com.example.onlinemonitoring.serviceImpl.YggxsensorServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 荧光光纤
 */
@Service("yggxCom")
@Scope("prototype")
public class YggxCom extends CommPortManager {
    @Autowired
    private YggxsensorServiceImpl yggxserviceimpl;
    @Autowired
    LanguageManager languageManager;
    String recvmsg[] = new String[4];

    public void ClearCache() {
        for (int i = 0; i < recvmsg.length; i++) {
            recvmsg[i] = "";
        }
    }

    @Override
    public void receiveDatas(String str) {
        //setText(str+"receiveDatas");
        if (ad.getCommunicationmode() == 4) {
            // read61850(str);
        } else {
            switch (ad.getBrand()) {
                case "1":
                    Datald(str);
                    break;
                case "2":
                    Datahq(str);
                    break;
                case "3":
                    Datayn(str);
                    break;
                case "4":
                    Datafy(str);
                    break;
                default:
                    return;
            }
        }
    }

    private void Datald(String str) {
        str = str.toUpperCase();
        setText(str);
        float[] temp = new float[32];
        int ckaddr = 0;
        reSend[addrindex] = 0;
        addrindex++;
        String addrstr = str.substring(0, 2);
        Integer addrint = parseHex4(addrstr);
        Yggxsensor yggx = new Yggxsensor();
        yggx.setStationid(ad.getStationid());
        yggx.setDeviceaddr(addrint);
        yggx.setDevicegroup(ad.getDevicegroup());
        MyResult<Yggxsensor> res = yggxserviceimpl.getList(yggx);
        if (res.getCount() == 0) {
            setText("当前数据库组" + ad.getDevicegroup() + "无地址：" + addrint + " ！ 请先添加该地址！");
            return;
        }
        setText(languageManager.getLan().getDeviceReturnedData() + "：" + languageManager.getLan().getStationID() + "："
                + ad.getStationid()
                + languageManager.getLan().getDeviceGroup() + " ：" + addrint
                + languageManager.getLan().getDeviceAddress()
                + "："
                + addrint);
        for (int j = 0; j < res.getCount(); j++) {
            if ((j * 8 + 14) > str.length()) {
                return;
            }
            Yggxsensor record = res.getData().get(j);
            ckaddr = (j * 8);
            if (str.substring(6 + ckaddr, 14 + ckaddr) == null) {
                setText("当前数据库组" + ad.getDevicegroup() + "：设备地址" + addrint + " 通道数量与参数不一致，请前往修改！");
                return;
            }
            byte[] mybyte_Temp = HexUtil.hexString2Bytes(
                    str.substring(10 + ckaddr, 14 + ckaddr) + str.substring(6 + ckaddr, 10 + ckaddr));
            temp[j] = HexUtil.byte2float(mybyte_Temp);
            setText(languageManager.getLan().getPointAddress() + (j + 1) + languageManager.getLan().getTemperature()
                    + temp[j]);
            yggx.setPointaddr(record.getPointaddr());
            yggx.setLasttemper(temp[j]);
            yggx.setLastdatatime(new Date());
            AddAndUpdate(record, yggx);
        }
    }

    private void Datahq(String str) {
        str = str.toUpperCase();
        setText(str);
        float[] temp = new float[32];
        int ckaddr = 0;
        reSend[addrindex] = 0;
        addrindex++;
        String addrstr = str.substring(0, 2);
        Integer addrint = parseHex4(addrstr);
        Yggxsensor yggx = new Yggxsensor();
        yggx.setStationid(ad.getStationid());
        yggx.setDeviceaddr(addrint);
        yggx.setDevicegroup(ad.getDevicegroup());
        MyResult<Yggxsensor> res = yggxserviceimpl.getList(yggx);
        if (res.getCount() == 0) {
            setText("当前数据库组" + ad.getDevicegroup() + "无地址：" + addrint + " ！ 请先添加该地址！");
            return;
        }
        setText(languageManager.getLan().getDeviceReturnedData() + "：" + languageManager.getLan().getStationID() + "："
                + ad.getStationid()
                + languageManager.getLan().getDeviceGroup() + " ：" + addrint
                + languageManager.getLan().getDeviceAddress()
                + "："
                + addrint);
        for (int j = 0; j < res.getCount(); j++) {
            if ((j * 4 + 14) > str.length()) {
                return;
            }
            Yggxsensor record = res.getData().get(j);
            ckaddr = (j * 8);
            if (str.substring(6 + ckaddr, 14 + ckaddr) == null) {
                setText("当前数据库组" + ad.getDevicegroup() + "：设备地址" + addrint + " 通道数量与参数不一致，请前往修改！");
                return;
            }
            temp[j] = parseHex4(str.substring(6 + ckaddr, 10 + ckaddr)) / 10f;
            setText(languageManager.getLan().getPointAddress() + (j + 1) + languageManager.getLan().getTemperature()
                    + temp[j]);
            yggx.setPointaddr(record.getPointaddr());
            yggx.setLasttemper(temp[j]);
            yggx.setLastdatatime(new Date());
            AddAndUpdate(record, yggx);
        }
    }

    private void Datayn(String str) {
        str = str.toUpperCase();
        setText(str);
        float[] temp = new float[32];
        int ckaddr = 0;
        reSend[addrindex] = 0;
        addrindex++;
        String addrstr = str.substring(0, 2);
        Integer addrint = parseHex4(addrstr);
        Yggxsensor yggx = new Yggxsensor();
        yggx.setStationid(ad.getStationid());
        yggx.setDeviceaddr(addrint);
        yggx.setDevicegroup(ad.getDevicegroup());
        MyResult<Yggxsensor> res = yggxserviceimpl.getList(yggx);
        if (res.getCount() == 0) {
            setText("当前数据库组" + ad.getDevicegroup() + "无地址：" + addrint + " ！ 请先添加该地址！");
            return;
        }
        if (str.length() < 34) {
            return;
        }
        setText(languageManager.getLan().getOpticalFiberDeviceReturnedData() + "："
                + languageManager.getLan().getStationID()
                + "："
                + ad.getStationid()
                + languageManager.getLan().getDeviceGroup() + " ：" + addrint
                + languageManager.getLan().getDeviceAddress()
                + "："
                + addrint);
        for (int j = 0; j < res.getCount(); j++) {
            if ((j * 4 + 14) > str.length()) {
                return;
            }
            Yggxsensor record = res.getData().get(j);
            ckaddr = (j * 4);
            if (str.substring(6 + ckaddr, 14 + ckaddr) == null) {
                setText("当前数据库组" + ad.getDevicegroup() + "：设备地址" + addrint + " 通道数量与参数不一致，请前往修改！");
                return;
            }
            temp[j] = parseHex4(str.substring(6 + ckaddr, 10 + ckaddr)) / 10f;
            if( temp[j]>500)
                continue;
            setText(languageManager.getLan().getPointAddress() + (j + 1) + languageManager.getLan().getTemperature()
                    + temp[j]);
            yggx.setPointaddr(record.getPointaddr());
            yggx.setLasttemper(temp[j]);
            yggx.setLastdatatime(new Date());
            AddAndUpdate(record, yggx);
        }
    }

    // @Override
    public void Datafy(String str) {
        str = str.toUpperCase();
        setText(str);
        float[] temp = new float[32];
        Integer startIndex = 0;// 数据起始位置
        reSend[addrindex] = 0;
        String addrstr = str.substring(0, 2);
        Integer addrint = parseHex4(addrstr);

        recvmsg[currcmd] = str.substring(6, str.length() - 4);
        float xinhao = 0, lv = 0, temperature = 0;
        int channelstatus = 0, jdq = 0;
        Yggxsensor yggx = new Yggxsensor();
        yggx.setStationid(ad.getStationid());
        yggx.setDeviceaddr(addrint);
        yggx.setDevicegroup(ad.getDevicegroup());
        MyResult<Yggxsensor> res = yggxserviceimpl.getList(yggx);
        if (res.getCount() == 0) {
            setText("当前数据库组" + ad.getDevicegroup() + "无地址：" + addrint + " ！ 请先添加该地址！");
            return;
        }
        setText(languageManager.getLan().getOpticalFiberDeviceReturnedData() + "："
                + languageManager.getLan().getStationID()
                + "："
                + ad.getStationid()
                + languageManager.getLan().getDeviceGroup() + " ：" + addrint
                + languageManager.getLan().getDeviceAddress()
                + "："
                + addrint);

        if (currcmd == 0) {
            for (int i = 0; i < res.getCount(); i++) {
                temperature = IEEE754Utils.strbytesToSingle(recvmsg[currcmd].substring(startIndex, startIndex += 8))
                        .floatValue();
                setText(languageManager.getLan().getTemperature() + "：" + temperature + "℃ ");
                // 查询对象
                Yggxsensor record = res.getData().get(i);
                if (record == null) {
                    setText("当前数据库无监测点：设备地址" + addrint + "的监测点" + (i + 1) + " ！ 请先添加该监测点！");
                    return;
                }
                if (record.getInuse() == 0)
                    return;
                yggx.setPointaddr(record.getPointaddr());
                yggx.setLasttemper(temperature);
                yggx.setLastxinhao(record.getLastxinhao());
                yggx.setLastlv(record.getLastlv());
                yggx.setLastjdq(record.getLastjdq());
                yggx.setLastchannelstatus(record.getLastchannelstatus());
                yggx.setLastdatatime(new Date());
                AddAndUpdate(record, yggx);
            }
        } else if (currcmd == 1) {
            for (int i = 0; i < res.getCount(); i++) {
                xinhao = IEEE754Utils.strbytesToSingle(recvmsg[currcmd].substring(startIndex, startIndex += 8))
                        .floatValue();
                setText("信号：" + xinhao + " ");
                // 查询对象
                Yggxsensor record = res.getData().get(i);
                if (record == null) {
                    setText("当前数据库无监测点：设备地址" + addrint + "的监测点" + (i + 1) + " ！ 请先添加该监测点！");
                    return;
                }
                if (record.getInuse() == 0)
                    return;
                yggx.setPointaddr(record.getPointaddr());
                yggx.setLastxinhao(xinhao);
                yggx.setLastcommunicationstatus(0);
                yggx.setLastdatatime(new Date());
                if (yggxserviceimpl.Update(yggx, false) == 0) {
                    setText("更新实时数据失败，请检查数据库连接");
                }
            }
        } else if (currcmd == 2) {
            for (int i = 0; i < res.getCount(); i++) {
                lv = IEEE754Utils.strbytesToSingle(recvmsg[currcmd].substring(startIndex, startIndex += 8))
                        .floatValue();
                setText("光值：" + lv + " ");
                // 查询对象
                Yggxsensor record = res.getData().get(i);
                if (record == null) {
                    setText("当前数据库无监测点：设备地址" + addrint + "的监测点" + (i + 1) + " ！ 请先添加该监测点！");
                    return;
                }
                if (record.getInuse() == 0)
                    return;
                yggx.setPointaddr(record.getPointaddr());
                yggx.setLastlv(lv);
                yggx.setLastcommunicationstatus(0);
                yggx.setLastdatatime(new Date());
                if (yggxserviceimpl.Update(yggx, false) == 0) {
                    setText("更新实时数据失败，请检查数据库连接");
                }
            }
            addrindex++;
        }
    }

    @Transactional
    private void AddAndUpdate(Yggxsensor record, Yggxsensor yggx) {
        int alarmLevel = 0;// 报警等级
        String alarmMessage = "";// 报警消息
        alarmLevel = GetAlarmStatus(isnull(yggx.getLasttemper()), isnull(record.getAlarmvalue()),
                isnull(record.getAlarmrelievevalue()), isnull(record.getWarnvalue()),
                isnull(record.getWarnrelievevalue()),
                isnull(record.getLastalarmlevel()), true,
                languageManager.getLan().getFiberMonitoringPoint() + record.getPointaddr(),
                record.getDevicegroup(),
                record.getDeviceaddr(), record.getPointname(), record.getPointaddr());
        alarmMessage += GetAlarmMessage(alarmLevel, languageManager.getLan().getTemperature());
        switch (ad.getBrand()) {
            case "1":
                break;
            case "2":
                if (yggx.getLasttemper() == 3000) {
                    alarmLevel = 2;
                    alarmMessage += languageManager.getLan().getFiberPossiblyDamaged() + ",";
                }
                if (yggx.getLasttemper() == -437) {
                    alarmLevel = 2;
                    alarmMessage += languageManager.getLan().getSensorModulePossiblyDamaged() + ",";
                }
                break;
            case "3":
                break;
            case "4":
                // int channelstatus = yggx.getLastchannelstatus();
                // if(channelstatus==0)
                // {
                // //setText("通道状态：" + yggx.getPointaddr() + " OK" );
                // }
                // if(channelstatus==9)
                // {
                // //setText("通道状态：" + yggx.getPointaddr() + " OFF" );
                // alarmLevel = 2;
                // alarmMessage += "通道状态：OFF" ;
                // }
                // else
                // {
                // //setText("通道状态：" + yggx.getPointaddr() + " error "+ channelstatus +" " );
                // alarmLevel = 2;
                // alarmMessage += "通道状态：error"+ channelstatus +" " ;
                // }
                // int jdq = yggx.getLastjdq();
                // if((jdq&0x01)==1)
                // ;
                // else
                // {
                // alarmLevel = 2;
                // alarmMessage += "继电器1:"+ " 不满足条件" ;
                // }
                // if((jdq&0x02)==1)
                // ;
                // else
                // {
                // alarmLevel = 2;
                // alarmMessage += "继电器2:"+ " 不满足条件" ;
                // }
                // if((jdq&0x04)==1)
                // ;
                // else
                // {
                // alarmLevel = 2;
                // alarmMessage += "继电器3:"+ " 不满足条件" ;
                // }
                // if((jdq&0x08)==1)
                // ;
                // else
                // {
                // alarmLevel = 2;
                // alarmMessage += "继电器4:"+ " 不满足条件" ;
                // }
                // if((jdq&0x16)==1)
                // ;
                // else
                // {
                // alarmLevel = 2;
                // alarmMessage += "继电器5:"+ " 不满足条件" ;
                // }
                // if((jdq&0x32)==1)
                // ;
                // else
                // {
                // alarmLevel = 2;
                // alarmMessage += "继电器6:"+ " 不满足条件" ;
                // }
                break;
            default:
                return;
        }
        yggx.setLastalarmlevel(alarmLevel);
        yggx.setLastalarmmessage(alarmMessage);
        yggx.setLastcommunicationstatus(0);
        yggx.setLasthisdatatime(addHistory(record));
        if (yggxserviceimpl.Update(yggx, false) == 0) {
            setText("更新实时数据失败，请检查数据库连接");
        }
    }

    private Date addHistory(Yggxsensor sensor) {
        if (sensor != null) {
            if (sensor.getLasthisdatatime() == null) {
                add(sensor);
                return new Date();
            } else {
                long lasttime = 0;
                long nowtime = 0;
                try {
                    lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                    nowtime = HexUtil.todate(new Date()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                int timersp = 60000;
                if (sensor.getLastalarmlevel() != 0) {
                    timersp = ad.getHisalarmtimersp() * 1000;
                } else {
                    timersp = ad.getHistimersp() * 1000;
                }
                if (lasttime + timersp < nowtime) {
                    add(sensor);
                    return new Date();
                }
            }
        }
        return null;
    }

    private void add(Yggxsensor sensor) {
        Yggxhistory his = new Yggxhistory();
        his.setStationid(sensor.getStationid());
        his.setDeviceaddr(sensor.getDeviceaddr());
        his.setAddrname(sensor.getAddrname());
        his.setDevicegroup(sensor.getDevicegroup());
        his.setPointaddr(sensor.getPointaddr());
        his.setPointname(sensor.getPointname());
        his.setBrand(sensor.getBrand());
        his.setTemper(sensor.getLasttemper());
        his.setXinhao(sensor.getLastxinhao());
        his.setLv(sensor.getLastlv());
        his.setJdq(sensor.getLastjdq());
        his.setChannelstatus(sensor.getLastchannelstatus());
        his.setDatatime(sensor.getLastdatatime());
        his.setAlarmlevel(sensor.getLastalarmlevel());
        his.setAlarmmessage(sensor.getLastalarmmessage());
        yggxserviceimpl.Add(his);
    }

    @Async("threadPool")
    public void startSendThread(Appdevice Appdevice) throws Exception {

        checkType = "crc16";
        issend.put(Thread.currentThread().getId(), true);
        String cstr = "";
        String cmd[] = Appdevice.getCmd().split(",");
        String nametype = "";
       
        while (issend.get(Thread.currentThread().getId()) != null) {
            rlock.lock();
            try {
                if (isrun) {
                    if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                        addrindex = Appdevice.getAddrmin();
                    currcmd = 0;
                    for (int i = 0; i < cmd.length; i++) {
                        if (currcmd == 0) {
                            ClearCache();
                        }
                        Appdevice.setName(languageManager.getLan().getNameOptical());
                        cstr = String.format(cmd[currcmd], String.format("%02X", addrindex));
                        cstr += CRC16.calcCrc16(cstr);
                        Send(cstr);
                        sendCondition.await(timeoutsp, TimeUnit.MILLISECONDS);
                        currcmd++;
                    }
                    if (reSend[addrindex] > 3) {
                        yggxserviceimpl.UpdateStatus(ad, addrindex, 1);
                        reSend[addrindex] = 0;
                        addrindex++;
                    }
                    reSend[addrindex]++;
                } else if (rescode != 0) {
                    setText(resmsg[rescode]);
                }
            } catch (Exception e) {
                // TODO: handle exception
            } finally {
                rlock.unlock();
            }
        }
    }
}
